<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.9.1"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Agile Modbus: Example description</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="navtreedata.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr style="height: 56px;">
  <td id="projectalign" style="padding-left: 0.5em;">
   <div id="projectname">Agile Modbus
   &#160;<span id="projectnumber">1.1.4</span>
   </div>
   <div id="projectbrief">Lightweight modbus protocol stack.</div>
  </td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.9.1 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
var searchBox = new SearchBox("searchBox", "search",false,'Search','.html');
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
$(function() {
  initMenu('',true,false,'search.php','Search');
  $(document).ready(function() { init_search(); });
});
/* @license-end */</script>
<div id="main-nav"></div>
</div><!-- top -->
<div id="side-nav" class="ui-resizable side-nav-resizable">
  <div id="nav-tree">
    <div id="nav-tree-contents">
      <div id="nav-sync" class="sync"></div>
    </div>
  </div>
  <div id="splitbar" style="-moz-user-select:none;" 
       class="ui-resizable-handle">
  </div>
</div>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
$(document).ready(function(){initNavTree('md__home_runner_work_agile_modbus_agile_modbus_examples__r_e_a_d_m_e.html',''); initResizable(); });
/* @license-end */
</script>
<div id="doc-content">
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0" 
        name="MSearchResults" id="MSearchResults">
</iframe>
</div>

<div class="PageDoc"><div class="header">
  <div class="headertitle">
<div class="title">Example description </div>  </div>
</div><!--header-->
<div class="contents">
<div class="textblock"><h1><a class="anchor" id="autotoc_md15"></a>
1. Introduction</h1>
<p>This example provides functional demonstration of RTU / TCP master and slave.</p>
<p>Using <code>cmake</code> under <code>WSL</code> or <code>Linux</code>, you can directly compile all examples and run the test program on your computer.</p>
<p>Directory Structure:</p>
<table class="markdownTable">
<tr class="markdownTableHead">
<th class="markdownTableHeadNone">Name   </th><th class="markdownTableHeadNone">Description    </th></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone">common   </td><td class="markdownTableBodyNone">public source code    </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyNone">figures   </td><td class="markdownTableBodyNone">materials    </td></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone">rtu_master   </td><td class="markdownTableBodyNone">RTU master example    </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyNone">tcp_master   </td><td class="markdownTableBodyNone">TCP master example    </td></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone">slave   </td><td class="markdownTableBodyNone">RTU + TCP slave example    </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyNone">rtu_p2p   </td><td class="markdownTableBodyNone">RTU peer-to-peer transfer file    </td></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone">rtu_broadcast   </td><td class="markdownTableBodyNone">RTU broadcast transmission file (sticky packet processing example)   </td></tr>
</table>
<h1><a class="anchor" id="autotoc_md16"></a>
2. Use</h1>
<p>The tools you need to prepare are as follows:</p>
<ul>
<li>Virtual serial port software</li>
<li>Modbus Poll</li>
<li>Modbus Slave</li>
</ul>
<p>Type <code>cmake -B build</code> 、 <code>cmake --build build</code> on the command line.</p>
<h2><a class="anchor" id="autotoc_md17"></a>
2.1. Host</h2>
<ul>
<li>RTU (rtu_master)<ul>
<li><p class="startli">Use virtual serial port software to virtualize a pair of serial ports</p>
<p class="startli"><img src="./figures/VirtualCom.jpg" alt="VirtualCom" class="inline"/></p>
</li>
<li><p class="startli">Open <code>Modbus Slave</code> and set as shown below</p>
<p class="startli"><img src="./figures/ModbusSlaveSetup.jpg" alt="ModbusSlaveSetup" class="inline"/></p>
</li>
<li><p class="startli"><code>Modbus Slave</code> connection, set as shown below</p>
<p class="startli"><img src="./figures/ModbusSlaveRTUConnection.jpg" alt="ModbusSlaveRTUConnection" class="inline"/></p>
</li>
<li><p class="startli">Enter the <code>build/bin</code> directory, <code>./RtuMaster /dev/ttySX</code> to run the <code>RTU</code> host example, <code>ttySX</code> is the other of a pair of virtual serial ports</p>
<p class="startli"><img src="./figures/RTUMaster.jpg" alt="RTUMaster" class="inline"/></p>
</li>
</ul>
</li>
<li>TCP (tcp_master)<ul>
<li>Open <code>Modbus Slave</code>, <code>SetUp</code> settings are consistent with <code>RTU</code></li>
<li><p class="startli"><code>Modbus Slave</code> connection, set as shown below</p>
<p class="startli"><img src="./figures/ModbusSlaveTCPConnection.jpg" alt="ModbusSlaveTCPConnection" class="inline"/></p>
</li>
<li><p class="startli">Enter the <code>build/bin</code> directory, <code>./TcpMaster 127.0.0.1 502</code> and run the <code>TCP</code> host example</p>
<p class="startli"><img src="./figures/TCPMaster.jpg" alt="TCPMaster" class="inline"/></p>
</li>
</ul>
</li>
</ul>
<h2><a class="anchor" id="autotoc_md18"></a>
2.2. Slave machine</h2>
<ul>
<li>This example (slave) provides both <code>RTU</code> and <code>TCP</code> slave function demonstrations, controlling the same memory. <code>TCP</code> can connect to a maximum of 5 clients. Each client has a no-data timeout of 10s and will be automatically disconnected after 10s.</li>
<li>The example supports all function codes (except function code 0x07).</li>
<li><code>bit</code>, <code>input_bit</code>, <code>register</code>, <code>input_register</code> registers are defined separately for each file.</li>
<li>Use <code>agile_modbus_slave_util_callback</code>.</li>
<li>Register address field:</li>
</ul>
<table class="markdownTable">
<tr class="markdownTableHead">
<th class="markdownTableHeadNone">Register   </th><th class="markdownTableHeadNone">Address range    </th></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone">Coil register   </td><td class="markdownTableBodyNone">0x041A ~ 0x0423 (1050 ~ 1059)    </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyNone">Discrete input register   </td><td class="markdownTableBodyNone">0x041A ~ 0x0423 (1050 ~ 1059)    </td></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone">Holding register   </td><td class="markdownTableBodyNone">0xFFF6 ~ 0xFFFF (65526 ~ 65535)    </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyNone">Input register   </td><td class="markdownTableBodyNone">0xFFF6 ~ 0xFFFF (65526 ~ 65535)   </td></tr>
</table>
<p><b>Note</b>: Reading and writing other address registers can be successful, but the values ​​are all 0.</p>
<p>use:</p>
<ul>
<li><p class="startli">Use virtual serial port software to virtualize a pair of serial ports</p>
<p class="startli"><img src="./figures/VirtualCom.jpg" alt="VirtualCom" class="inline"/></p>
</li>
<li><p class="startli">Enter the <code>build/bin</code> directory, <code>./ModbusSlave /dev/ttyS2 1025</code> to run the example</p>
<p class="startli">/dev/ttySX: One of the virtual serial ports</p>
<p class="startli">1025: Listening port number. If you do not have <code>root</code> permissions, the port number must be greater than <code>1024</code></p>
</li>
<li><p class="startli">Open <code>Modbus Poll</code> and set and connect RTU as shown below</p>
<p class="startli"><img src="./figures/ModbusPollSetup.jpg" alt="ModbusPollSetup" class="inline"/></p>
<p class="startli"><img src="./figures/ModbusPollRTUConnection.jpg" alt="ModbusPollRTUConnection" class="inline"/></p>
</li>
<li><p class="startli">Open 5 <code>Modbus Poll</code>, set the same as RTU, and connect as shown below</p>
<p class="startli"><img src="./figures/ModbusPollTCPConnection.jpg" alt="ModbusPollTCPConnection" class="inline"/></p>
</li>
<li><p class="startli">Effect demonstration</p>
<p class="startli"><img src="./figures/ModbusSlaveShow.jpg" alt="ModbusSlaveShow" class="inline"/></p>
</li>
<li><p class="startli">Timeout disconnect demonstration</p>
<p class="startli">Close the poll interface of <code>Modbus Poll</code> and look at the console print to see the close message.</p>
<p class="startli"><img src="./figures/ModbusSlaveTimeoutShow.jpg" alt="ModbusSlaveTimeoutShow" class="inline"/></p>
</li>
</ul>
<h2><a class="anchor" id="autotoc_md19"></a>
2.3. RTU transmission file</h2>
<p><img src="./figures/ModbusProtocol.jpg" alt="ModbusProtocol" class="inline"/></p>
<p>Use <code>0x50</code> as the special function code for transferring files.</p>
<p>File data is transferred in packets, with a maximum size of 1024 bytes per packet.</p>
<p><code>Data</code> field protocol definition:</p>
<ul>
<li>Host request</li>
</ul>
<table class="markdownTable">
<tr class="markdownTableHead">
<th class="markdownTableHeadNone">command   </th><th class="markdownTableHeadNone">number of bytes   </th><th class="markdownTableHeadNone">data    </th></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone">2 Bytes   </td><td class="markdownTableBodyNone">2 Bytes   </td><td class="markdownTableBodyNone">N Bytes   </td></tr>
</table>
<p>Order:</p>
<table class="markdownTable">
<tr class="markdownTableHead">
<th class="markdownTableHeadNone">Command   </th><th class="markdownTableHeadNone">Description   </th><th class="markdownTableHeadNone">Data    </th></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone">0x0001   </td><td class="markdownTableBodyNone">Start sending   </td><td class="markdownTableBodyNone">File size (4 Bytes) + file name (string)    </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyNone">0x0002   </td><td class="markdownTableBodyNone">Transmission data   </td><td class="markdownTableBodyNone">Flag (1 Byte) + file data   </td></tr>
</table>
<p>Logo:</p>
<table class="markdownTable">
<tr class="markdownTableHead">
<th class="markdownTableHeadNone">Status   </th><th class="markdownTableHeadNone">Description    </th></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone">0x00   </td><td class="markdownTableBodyNone">The last packet of data    </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyNone">0x01   </td><td class="markdownTableBodyNone">Not the last packet of data   </td></tr>
</table>
<ul>
<li>Slave response</li>
</ul>
<table class="markdownTable">
<tr class="markdownTableHead">
<th class="markdownTableHeadNone">Command   </th><th class="markdownTableHeadNone">Status    </th></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone">2 Bytes   </td><td class="markdownTableBodyNone">1 Byte   </td></tr>
</table>
<p>state:</p>
<table class="markdownTable">
<tr class="markdownTableHead">
<th class="markdownTableHeadNone">Status   </th><th class="markdownTableHeadNone">Description    </th></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone">0x00   </td><td class="markdownTableBodyNone">Failure    </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyNone">0x01   </td><td class="markdownTableBodyNone">Success   </td></tr>
</table>
<ul>
<li><p class="startli">Use virtual serial port software to virtualize 3 serial ports to form a serial port group</p>
<p class="startli">Here I use the MX virtual serial port</p>
<p class="startli"><img src="./figures/VirtualComGroup.jpg" alt="VirtualComGroup" class="inline"/></p>
</li>
</ul>
<h3><a class="anchor" id="autotoc_md20"></a>
2.3.1. Point-to-point transmission</h3>
<ul>
<li><p class="startli">Enter the <code>build/bin</code> directory and open <code>Linux Shell</code>. The demonstration effect is as follows</p>
<p class="startli"><b>Notice</b>:</p><ul>
<li>The transferred files must be general files. Executable files, directories, etc. are not supported.</li>
<li>The file path must be the path in <code>Linux</code> environment</li>
<li>After the slave receives the data, the file name is modified (slave address_original file name) and written in the current directory.</li>
</ul>
<p class="startli"><img src="./figures/rtu_p2p.gif" alt="rtu_p2p" class="inline"/></p>
</li>
</ul>
<h3><a class="anchor" id="autotoc_md21"></a>
2.3.2. Broadcast transmission</h3>
<p>This example mainly demonstrates the use of <code>frame_length</code> in <code>agile_modbus_slave_handle</code>.</p>
<p>In <code>broadcast_master</code>, use broadcast address 0 and send data packets every 5ms. At the same time, 100 bytes of dirty data are sent after each packet of data.</p>
<div class="fragment"><div class="line"><span class="keywordtype">int</span> send_len = <a class="code" href="group___master___raw___operation___functions.html#ga933c935a47f59cac74bcec545d266a4e">agile_modbus_serialize_raw_request</a>(ctx, raw_req, raw_req_len);</div>
<div class="line">serial_send(_fd, ctx-&gt;send_buf, send_len);</div>
<div class="line"> </div>
<div class="line"><span class="comment">//dirty data</span></div>
<div class="line">serial_send(_fd, _dirty_buf, <span class="keyword">sizeof</span>(_dirty_buf));</div>
<div class="ttc" id="agroup___master___raw___operation___functions_html_ga933c935a47f59cac74bcec545d266a4e"><div class="ttname"><a href="group___master___raw___operation___functions.html#ga933c935a47f59cac74bcec545d266a4e">agile_modbus_serialize_raw_request</a></div><div class="ttdeci">int agile_modbus_serialize_raw_request(agile_modbus_t *ctx, const uint8_t *raw_req, int raw_req_length)</div><div class="ttdoc">Pack the original data into a request message.</div><div class="ttdef"><b>Definition:</b> <a href="agile__modbus_8c_source.html#l01031">agile_modbus.c:1031</a></div></div>
</div><!-- fragment --><p>Under such a fast data flow, <code>broadcast_slave</code> must use the <code>frame_length</code> parameter in <code>agile_modbus_slave_handle</code> to handle sticky packets.</p>
<ul>
<li><p class="startli">Enter the <code>build/bin</code> directory and open <code>Linux Shell</code>. The demonstration effect is as follows</p>
<p class="startli"><b>Notice</b>:</p><ul>
<li>The transferred files must be general files. Executable files, directories, etc. are not supported.</li>
<li>The file path must be the path in <code>Linux</code> environment</li>
<li>After the slave receives the data, the file name is modified (slave address_original file name) and written in the current directory.</li>
</ul>
<p class="startli"><img src="./figures/rtu_broadcast.gif" alt="rtu_broadcast" class="inline"/> </p>
</li>
</ul>
</div></div><!-- contents -->
</div><!-- PageDoc -->
</div><!-- doc-content -->
<!-- start footer part -->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
  <ul>
    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.1 </li>
  </ul>
</div>
</body>
</html>
